package com.fullstack.server.core

import cats.*
import cats.effect.Sync
import cats.implicits.*
import com.fullstack.server.domain.user.User
import doobie.*
import doobie.implicits.*
import doobie.postgres.implicits.*
import doobie.util.*
import doobie.util.transactor.Transactor


trait Users[F[_]] {

  def findByUserId(id: String): F[Option[User]]

  def create(user: User): F[Int]

  def update(user: User): F[Option[User]]
  

}

class LiveUsers[F[_]: Sync] private (xa: Transactor[F]) extends Users[F] {
  

  override def findByUserId(id: String): F[Option[User]] =
    sql"""
         SELECT * FROM users
         WHERE id = ${id} and status = 1
         """
      .query[User].option.transact(xa)

  override def create(u: User): F[Int] =
    sql"""
      INSERT INTO users(id, name, age)
      VALUES (${u.id}, ${u.name}, ${u.age} )
         """.update.run.transact(xa)


  override def update(user: User): F[Option[User]] =
    for
      _ <-
        sql"""
         UPDATE users
         SET user_phone = ${user.name},
             user_name = ${user.age}
         WHERE id = ${user.id}
         """.update.run.transact(xa)
      maybeUser <- findByUserId(user.id)
    yield maybeUser
  
}

object LiveUsers {
  def apply[F[_]: Sync](xa: Transactor[F]): F[LiveUsers[F]] =
    new LiveUsers[F](xa).pure[F]

}